package com.example.base.security.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.base.excetion.GlobalExcetion;
import com.example.base.security.domain.SysMenuEntity;
import com.example.base.security.domain.SysRoleEntity;
import com.example.base.security.domain.SysRoleMenuEntity;
import com.example.base.security.domain.SysUserRoleEntity;
import com.example.base.security.domain.vo.SysRoleMenuVo;
import com.example.base.security.mapper.SysRoleMenuMapper;
import com.example.base.security.service.SysMenuService;
import com.example.base.security.service.SysRoleMenuService;
import com.example.base.security.service.SysRoleService;
import com.example.base.security.service.SysUserRoleService;
import com.example.base.system.domain.SysApi;
import com.example.base.system.domain.SysRoleApi;
import com.example.base.system.service.SysApiService;
import com.example.base.system.service.SysRoleApiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Xiongx
 * @version 1.0
 * @date 2021/6/11 14:49
 * @since JDK 1.8
 */
@Transactional
@Service("sysRoleMenuService")
public class SysRoleMenuServiceImpl extends ServiceImpl<SysRoleMenuMapper, SysRoleMenuEntity> implements SysRoleMenuService {

    @Cacheable(cacheNames = "getById",key = "#id")
    @Override
    public SysRoleMenuEntity getById(Serializable id) {
        return super.getById(id);
    }

    @Override
    public IPage<SysRoleMenuEntity> page(Integer pageNum, Integer pageSize, String roleId) {
        LambdaQueryWrapper<SysRoleMenuEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        IPage<SysRoleMenuEntity> page=this.baseMapper.selectPage(new Page(pageNum,pageSize),lambdaQueryWrapper);
        return page;
    }

    @Override
    public SysRoleMenuEntity getSysRoleMenuEntityRidMid(Serializable rid, Serializable mid) {
        LambdaQueryWrapper<SysRoleMenuEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysRoleMenuEntity::getMenuId,mid);
        lambdaQueryWrapper.eq(SysRoleMenuEntity::getRoleId,rid);
        SysRoleMenuEntity sysRoleMenuEntity=this.baseMapper.selectOne(lambdaQueryWrapper);
        return sysRoleMenuEntity;
    }

    @Override
    public List<SysRoleMenuEntity> getSysRoleMenuEntityRid(Serializable rid) {
        LambdaQueryWrapper<SysRoleMenuEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysRoleMenuEntity::getRoleId,rid);
        List<SysRoleMenuEntity> list = this.baseMapper.selectList(lambdaQueryWrapper);
        return list;
    }

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Autowired
    private SysRoleApiService sysRoleApiService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private SysApiService sysApiService;

    @Override
    public List<SysRoleMenuEntity> getSysRoleMenuEntityUid(Serializable uid) {
        List<SysUserRoleEntity> list=sysUserRoleService.selectUserRoleEntityByUid(uid);
        if(list==null){
            return Collections.emptyList();
        }
        List<Integer> roleIds=list.stream().map(SysUserRoleEntity::getRoleId).collect(Collectors.toList());
        LambdaQueryWrapper<SysRoleMenuEntity> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(SysRoleMenuEntity::getRoleId,roleIds);
        List<SysRoleMenuEntity> sysRoleMenuEntities=this.baseMapper.selectList(lambdaQueryWrapper);
        return sysRoleMenuEntities;
    }

    @Override
    public void addSysRoleMenu(SysRoleMenuVo vo) throws GlobalExcetion {
        SysRoleEntity sysRoleEntity=sysRoleService.getById(vo.getRoleId());
        if(sysRoleEntity==null){
            throw new GlobalExcetion(1,"角色不存在");
        }
        List<SysRoleMenuEntity> entityList=getSysRoleMenuEntityRid(vo.getRoleId());
        if(entityList!=null && entityList.size() >0){
            for (int i = 0; i < entityList.size() ; i++) {
                SysRoleMenuEntity entity=entityList.get(i);
                if(!vo.getMenuIds().contains(entity.getMenuId())){
                    sysRoleMenuService.removeById(entity.getId());
                }
            }
        }
        for(Integer id: vo.getMenuIds()){
            SysMenuEntity menuEntity=sysMenuService.getById(id);
            if(menuEntity==null){
                continue;
            }
            SysRoleMenuEntity entity=getSysRoleMenuEntityRidMid(sysRoleEntity.getRoleId(),id);
            if(entity!=null){
                continue;
            }
            SysRoleMenuEntity sysRoleMenuEntity=new SysRoleMenuEntity(sysRoleEntity.getRoleId(),id);
            this.baseMapper.insert(sysRoleMenuEntity);
        }
        if(vo.getApiIds()!=null){
            List<SysRoleApi> sysRoleApis=sysRoleApiService.getSysRoleApiListByRoleId(vo.getRoleId()+"");
            if(sysRoleApis!=null && sysRoleApis.size()>0){
                for (int i = 0; i < sysRoleApis.size() ; i++) {
                    SysRoleApi api=sysRoleApis.get(i);
                    if(!vo.getApiIds().contains(api.getId())){
                        super.baseMapper.deleteById(api.getId());
                    }
                }
            }
            for(Integer id:vo.getApiIds()){
                SysApi sysApi=sysApiService.getById(id);
                if(sysApi==null){
                    continue;
                }
                SysRoleApi entiry=sysRoleApiService.getSysRoleApiByRoleIdAndApiId(vo.getRoleId()+"",id+"");
                if(entiry==null){
                    SysRoleApi sysRoleApi=new SysRoleApi();
                    sysRoleApi.setApiId(String.valueOf(id));
                    sysRoleApi.setRoleId(String.valueOf(vo.getRoleId()));
                    sysRoleApiService.save(sysRoleApi);
                }
            }
        }
    }
}
